package net.odtel.mailadmin.dao;

import java.util.Calendar;
import org.joda.time.DateTime;
import java.util.List;

import javax.mail.Session;

import net.odtel.mailadmin.model.EmailAccount;
import net.odtel.mailadmin.model.EmailDomain;

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Property;
import org.hibernate.validator.constraints.Range;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class EmailAccountDAOImpl extends HibernateDaoSupport implements
		EmailAccountDAO {

	@Transactional(propagation = Propagation.REQUIRED)
	public void add(EmailAccount emailAccount) {
		long timeNow = Calendar.getInstance().getTimeInMillis();

		emailAccount.setCreated(new DateTime(timeNow));
		emailAccount.setModified(new DateTime(timeNow));
		emailAccount.setLocal_part(emailAccount.getUsername());
		emailAccount.setMaildir(emailAccount.getDomain());
		getHibernateTemplate().save(emailAccount);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public EmailAccount findByLogin(String login) {
		DetachedCriteria query = DetachedCriteria.forClass(EmailAccount.class)
				.add(Property.forName("username").eq(login));
		List<EmailAccount> list = getHibernateTemplate().findByCriteria(query);
		if (list.size() > 0)
			return (EmailAccount) list.get(0);
		return null;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public List<EmailAccount> findAll() {
		return (List<EmailAccount>) getHibernateTemplate().find(
				" from " + EmailAccount.class.getName());
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void remove(EmailAccount emailAccount) {
		getHibernateTemplate().delete(emailAccount);

	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void update(EmailAccount emailAccount) {
		getHibernateTemplate().update(emailAccount);

	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void remove(Long emailAccountId) {
		EmailAccount emailAccount = getHibernateTemplate().load(
				EmailAccount.class, emailAccountId);
		if (emailAccount != null)
			getHibernateTemplate().delete(emailAccount);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public EmailAccount findById(Long emailAccountId) {
		EmailAccount emailAccount = getHibernateTemplate().get(
				EmailAccount.class, emailAccountId);
		if (emailAccount != null)
			return (emailAccount);
		return null;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean ifExist(String login) {
		DetachedCriteria query = DetachedCriteria.forClass(EmailAccount.class)
				.add(Property.forName("username").eq(login));
		List<EmailAccount> list = getHibernateTemplate().findByCriteria(query);
		if (list.size() > 0)
			return true;
		return false;

		
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public List<EmailAccount> findRange(int[] range) {

		Criteria criteria = getHibernateTemplate().getSessionFactory()
				.getCurrentSession().createCriteria(EmailAccount.class);
		
		criteria.addOrder(Order.asc("username"))
				.setMaxResults(range[1] - range[0]).setFirstResult(range[0]);

		return (List<EmailAccount>)criteria.list();

	}

	@Transactional(propagation = Propagation.REQUIRED)
	public boolean inDomain(String domain) {
		DetachedCriteria query = DetachedCriteria.forClass(EmailDomain.class)
				.add(Property.forName("domain").eq(domain));
		List<EmailDomain> list = (List<EmailDomain>) getHibernateTemplate()
				.findByCriteria(query);
		if (list.size() > 0)
			return true;
		return false;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public int count() {
		Criteria criteria = getHibernateTemplate().getSessionFactory()
				.getCurrentSession().createCriteria(EmailAccount.class);
		return criteria.list().size();
	
	}

}
